#include "printf.h"
#include "mem_map_table.h"
#include "syscounter.h"
#include "crg.h"
#include "irq.h"
#include "hal_api.h"

#define TCIP_BASE_ADDR           MEM_MAP_TCIP_BASE_ADDR

#define MTIMECMPLO_REG_ADDR      (TCIP_BASE_ADDR + 0x4000)
#define MTIMECMPHI_REG_ADDR      (TCIP_BASE_ADDR + 0x4004)
#define MTIMELO_REG_ADDR         (TCIP_BASE_ADDR + 0xBFF8)
#define MTIMEHI_REG_ADDR         (TCIP_BASE_ADDR + 0xBFFC)

static __IOM uint8_t rtc_irq_times;

static void mtimer_irq_handler(void *arg)
{
	(void)arg;
	printf("[INT NEST]: mtimer irq handle start\r\n");
	Hal_Irq_Disable(Machine_Timer_IRQn);
	Hal_Cnt_DelayUs(5*1000*1000);
	printf("[INT NEST]: mtimer irq handle end\r\n");
}

static void rtc_irq_handler(void *arg)
{
	(void)arg;
	printf("[INT NEST]: process rtc 1s irq\r\n");
	if (rtc_irq_times++ <= 5)
		Hal_Rtc_SetAlarm(1);
	else
		Hal_Irq_Disable(RTC_IRQn);
}

int32_t test_int_nest(void)
{
	uint64_t count = 0;
	uint64_t clk = get_mod_clk_rate(CRG_MOD_SYSCNT);

	printf("\r\n[INT NEST]: TEST START\r\n");

	Hal_Irq_Disable(RTC_IRQn);
	Hal_Irq_Disable(Machine_Software_IRQn);
	CLIC->CLICINT[Machine_Software_IRQn].IP = 0x00;
	CLIC->CLICINT[Machine_Software_IRQn].CTL |= (0x01 << 4);
	CLIC->CLICINT[RTC_IRQn].IP = 0x00;
	CLIC->CLICINT[RTC_IRQn].CTL |= (0x02 << 4);

	count = readl(MTIMEHI_REG_ADDR);
	count <<= 32;
	count |= readl(MTIMELO_REG_ADDR);
	//0.5s later to trigger mtimer int
	count += (clk >> 1);
	writel((uint32_t)(count >> 32), MTIMECMPHI_REG_ADDR);
	writel((uint32_t)count, MTIMECMPLO_REG_ADDR);
	Hal_Irq_Register(Machine_Timer_IRQn, mtimer_irq_handler, NULL);

	Hal_Rtc_Start();
	Hal_Rtc_RegisterCb(rtc_irq_handler);
	Hal_Rtc_SetAlarm(1);

	while(rtc_irq_times < 5);
	Hal_Rtc_Stop();
	Hal_Irq_Disable(Machine_Software_IRQn);
	rtc_irq_times = 0;

	printf("[INT NEST]: TEST END\r\n");

	return 0;
}


